/*
 * Copyright (C) 2010-2011 Graz University of Technology, Austria. All Rights reserved. 
 *
 * Contact: Simone Kopeinik <simone.kopeinik@tugraz.at>
 * 	   Graz University of Technology, Knowledge Management Institute, Brückenkopfgasse 1/6, 8020 Graz 	
 * 	   <http://www.kmi.tugraz.at/>
 * 
 * This software is part of the TARGET platform developed by the
 * TARGET EC-funded project www.reachyourtarget.org
 *
 * This software is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, version 3.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * The GNU General Public License is available at <http://www.gnu.org/licenses/>.
 *
 */
package at.tugraz.kmi.css.analyzer;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import at.tugraz.kmi.css.cbkst2.CbKSTCompetence;

/**
 * A UserCompetence does in contrast to a {@link CbKSTCompetence} mostly contain
 * user generated content and features.
 * 
 * @author Georg Öttl
 */
public class UserCompetence implements Serializable {

	private static final long		serialVersionUID	= 1L;

	private int						proficiency;

	private final CbKSTCompetence	competence;

	private String					competenceNameLong;

	private String					comment;

	/** Global variable: Maximum Proficiency Level */
	public static final int			MIN_PROFICIENCY		= 0;

	/** Global variable: Minimum Proficiency Level */
	public static final int			MAX_PROFICIENCY		= 100;

	private final List<String>		commentLines;					// lines of
	// a
	// comment
	// for
	// displaying
	// on a
	// visualization
	// viewer

	private final static int		CHARS_PER_LINE		= 31;

	private boolean					commentIsVisible	= false;

	/**
	 * 
	 * @param competence
	 *            The competence all generated user data is related to.
	 */
	public UserCompetence(CbKSTCompetence competence) {
		this.competence = competence;
		commentLines = new ArrayList<String>();
	}

	/**
	 * alternative long user generated competence name
	 * 
	 * @param competenceNameLong
	 */
	public void setCompetenceNameLong(String competenceNameLong) {
		this.competenceNameLong = competenceNameLong;
	}

	/**
	 * Getter for an alternative long user generated competence name
	 * 
	 * @return alternative long user generated competence name
	 * 
	 */
	public String getCompetenceNameLong() {
		return competenceNameLong;
	}

	/**
	 * Resets all user generated data set.
	 */
	public void reset() {
		setProficiency(0);
		setComment("");
	}

	/**
	 * Getter for the underlying competence.
	 * 
	 * @return The underlying competence
	 */
	public CbKSTCompetence getCompetence() {
		return competence;
	}

	/**
	 * 
	 * 
	 * @return The name of the underlying competence.
	 */
	public String getName() {
		return competence.getName();
	}

	/**
	 * Allows to set the proficiency level
	 * 
	 * @param proficiency
	 */
	public void setProficiency(int proficiency) {
		this.proficiency = Math.min(MAX_PROFICIENCY, proficiency);
		this.proficiency = Math.max(MIN_PROFICIENCY, this.proficiency);
	}

	/**
	 * Getter for the proficiency level.
	 * 
	 * @return the proficiency.
	 */
	public int getProficiency() {
		return proficiency;
	}

	/**
	 * Setter for a user comment to the competence.
	 * 
	 * @param annotation
	 *            The Comment
	 */
	public void setComment(String annotation) {
		if (annotation == null) {
			comment = "";
		} else {
			comment = annotation;
		}

		commentLines.clear();
		String[] lines = comment.split("\n");
		if (lines != null) {
			for (String line2 : lines) {
				String line = line2.replace("\r", "");
				String[] words = line.split(" ");
				if (line.length() <= CHARS_PER_LINE) {
					commentLines.add(line);
				} else {
					String commentLine = "";
					for (String word : words) {
						commentLine += word + " ";
						if (commentLine.length() > CHARS_PER_LINE) {
							commentLines.add(commentLine);
							commentLine = "";
						}
					}
					if (commentLine.length() > 0) {
						commentLines.add(commentLine);
					}
				}
			}
		}
		commentIsVisible = (commentLines.size() > 0);
	}

	/**
	 * 
	 * @return A line representation of the comments.
	 */
	public List<String> getCommentLines() {
		return commentLines;
	}

	/**
	 * User comment
	 * 
	 * @return User Comment.
	 */
	public String getComment() {
		return comment;
	}

	/**
	 * Set true if others/you want to see the comments.
	 * 
	 * @param visible
	 */
	public void setCommentVisible(boolean visible) {
		commentIsVisible = visible;
	}

	/**
	 * 
	 * @return true if the comment is visible
	 */
	public boolean isCommentVisible() {
		return commentIsVisible;
	}

	/**
	 * Creates net User Competence
	 * 
	 * @param name
	 *            The name of the Competence
	 * @return A new editable UserCompetence
	 */
	public static UserCompetence of(String name) {
		CbKSTCompetence competence2 = new CbKSTCompetence(name);
		competence2.setName(name);
		return new UserCompetence(competence2);
	}

	/**
	 * Creates a new UserCompetence
	 * 
	 * @param name
	 *            The name of the Competence
	 * 
	 * @param description
	 * 
	 * @return A new editable UserCompetence
	 */
	public static UserCompetence of(String name, String description) {
		CbKSTCompetence competence2 = new CbKSTCompetence(name);
		competence2.setName(name);
		competence2.setDescription(description);
		return new UserCompetence(competence2);
	}

	@Override
	public String toString() {
		return competence.getName();
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result
				+ ((competence == null) ? 0 : competence.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj) {
			return true;
		}
		if (obj == null) {
			return false;
		}
		if (getClass() != obj.getClass()) {
			return false;
		}
		UserCompetence other = (UserCompetence) obj;
		if (competence == null) {
			if (other.competence != null) {
				return false;
			}
		} else if (!competence.equals(other.competence)) {
			return false;
		}
		return true;
	}

}
